<!-- 修改自文件 src/pages/account/change-avatar.vue -->
<!-- https://advanced-cropper.github.io/vue-advanced-cropper/ -->
<template>
  <el-dialog
    v-model="state.dialogFormVisible"
    :title="t('article.listImage')"
    custom-class="dialog-min-width"
    @close="handleClose"
    :width="800"
    :destroy-on-close="true"
  >
    <el-row>
      <el-col :span="19">
        <!-- 长宽比 0.66 -->
        <!-- 长宽比 0.5 -->
        <Cropper
          ref="cropperRef"
          class="cropper"
          @change="onChange"
          :src="formEdit.image.src"
          :stencil-props="{ aspectRatio: state.aspectRatio }"
        />
        {{ t("article.pasteImageTip") }}
      </el-col>
      <el-col :span="5">
        <el-space direction="vertical">
          <el-text class="mx-1" size="large">{{
            t("account.preview")
          }}</el-text>
          <Preview
            v-if="state.dialogFormVisible"
            :width="150"
            :height="state.aspectRatio100Height"
            class="avatar"
            :image="formEdit.previewImage100"
            :coordinates="formEdit.previewCoordinates100"
          />
          <el-text class="mx-1">150 x {{ state.aspectRatio100Height }}</el-text>
          <br />
          <br />

          <Preview
            v-if="state.dialogFormVisible"
            :width="100"
            :height="state.aspectRatio50Height"
            class="avatar"
            :image="formEdit.previewImage50"
            :coordinates="formEdit.previewCoordinates50"
          />
          <el-text class="mx-1"
            >100 x {{ state.aspectRatio50Height }}</el-text
          ></el-space
        >
      </el-col>
    </el-row>

    <template #footer>
      <span class="dialog-footer">
        <el-button class="upload-button" @click="handleUpload">
          <input
            type="file"
            ref="fileRef"
            @change="loadImage($event)"
            accept="image/*"
          />
          {{ t("account.upload") }}
        </el-button>

        <el-button type="primary" @click="handleSubmit">{{
          t("common.submitButton")
        }}</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { reactive, ref, onMounted, getCurrentInstance } from "vue";
import "vue-advanced-cropper/dist/style.css";
import { CircleStencil, Cropper, Preview } from "vue-advanced-cropper";
import utils from "../../../utils/utils";
import { useStore } from "../../../stores/store";
import { useI18n } from "vue-i18n";
const { t } = useI18n({ useScope: "global" });
import apiUpload from "../../admin/api/upload";

// const { proxy } = getCurrentInstance() as any;
const store = useStore();
const cropperRef = ref();
const fileRef = ref();
const formRef = ref();
const loading = ref(false);

const emit = defineEmits<{
  (event: "on-submit-success", sender: string, fileId: string): void;
}>();

const state = reactive({
  // 1\2\3图书封面 布局类型影响图片比例
  layout: 1,
  aspectRatio: 10 / 6.6,
  aspectRatio100Height: 99,
  aspectRatio50Height: 66,
  businessKey: "",
  sender: "",
  dialogFormVisible: false,
});

const formEditOriginal = () => {
  return {
    avatarUrl: "",
    image: { src: null, type: null },
    coordinates: {
      width: 0,
      height: 0,
      left: 0,
      top: 0,
    },
    previewImage100: null,
    previewCoordinates100: null,
    previewImage50: null,
    previewCoordinates50: null,
  };
};
const formEdit = reactive(formEditOriginal());

const onChange = ({ coordinates, canvas, image }) => {
  formEdit.previewCoordinates100 = coordinates;
  // You able to do different manipulations at a canvas
  // but there we just get a cropped image, that can be used
  // as src for <img/> to preview result
  formEdit.previewImage100 = image;
  formEdit.previewCoordinates50 = coordinates;
  formEdit.previewImage50 = image;
};

// This function is used to detect the actual image type,
const getMimeType = (file, fallback = null) => {
  const byteArray = new Uint8Array(file).subarray(0, 4);
  let header = "";
  for (let i = 0; i < byteArray.length; i++) {
    header += byteArray[i].toString(16);
  }
  switch (header) {
    case "89504e47":
      return "image/png";
    case "47494638":
      return "image/gif";
    case "ffd8ffe0":
    case "ffd8ffe1":
    case "ffd8ffe2":
    case "ffd8ffe3":
    case "ffd8ffe8":
      return "image/jpeg";
    default:
      return fallback;
  }
};

const loadImage = (event) => {
  // Reference to the DOM input element
  const { files } = event.target;
  // Ensure that you have a file before attempting to read it
  if (files && files[0]) {
    // 1. Revoke the object URL, to allow the garbage collector to destroy the uploaded before file
    if (formEdit.image.src) {
      URL.revokeObjectURL(formEdit.image.src);
    }
    // 2. Create the blob link to the file to optimize performance:
    const blob = URL.createObjectURL(files[0]);

    // 3. The steps below are designated to determine a file mime type to use it during the
    // getting of a cropped image from the canvas. You can replace it them by the following string,
    // but the type will be derived from the extension and it can lead to an incorrect result:
    //
    // this.image = {
    //    src: blob;
    //    type: files[0].type
    // }

    // Create a new FileReader to read this image binary data
    const reader = new FileReader();
    // Define a callback function to run, when FileReader finishes its job
    reader.onload = (e) => {
      // Note: arrow function used here, so that "this.image" refers to the image of Vue component
      formEdit.image = {
        // Set the image source (it will look like blob:http://example.com/2c5270a5-18b5-406e-a4fb-07427f5e7b94)
        src: blob,
        // Determine the image type to preserve it during the extracting the image from canvas:
        type: getMimeType(e.target.result, files[0].type),
      };
    };
    // Start the reader job - read file as a data url (base64 format)
    reader.readAsArrayBuffer(files[0]);
  }
};

const handleUpload = () => {
  //   console.log("show", proxy.$refs, fileRef.value);
  fileRef.value.click();
};

const handleSubmit = async () => {
  // 处理业务逻辑，触发关闭事件
  loading.value = true;
  // apiUser
  //   .changeEmail(formEdit.email)
  //   .then((response: any) => {
  //     loading.value = false;
  //     console.log(response);
  //     if (response.data.code == 200) {
  //       state.dialogFormVisible = false;
  //       utils.infoNotification(t("common.submitSuccess"));
  //       emit("on-submit-success", formEdit.email);
  //     }
  //   })
  //   .catch((err: any) => {
  //     loading.value = false;
  //     utils.errorNotification(t("common.submitException"), err);
  //   });

  const { canvas } = cropperRef.value.getResult();
  if (canvas) {
    const formData = new FormData();
    canvas.toBlob((blob) => {
      formData.append("file", blob);
      formData.append("businessKey", state.businessKey);
      formData.append("category", "cms-list-image");
      // You can use axios, superagent and other libraries instead here
      apiUpload
        .uploadImage(formData)
        .then((response: any) => {
          loading.value = false;
          if (response.data.code == 200) {
            emit(
              "on-submit-success",
              // "/user/api/avatar/fileId.png"
              state.sender,
              response.data.data.fileId
            );
            utils.infoNotification(t("common.submitSuccess"));
            state.dialogFormVisible = false;
          }
        })
        .catch((err: any) => {
          loading.value = false;
          utils.errorNotification(t("common.submitException"), err);
        });
      //   fetch("http://example.com/upload/", {
      //     method: "POST",
      //     body: form,
      //   });
      // Perhaps you should add the setting appropriate file format here
    }, "image/jpeg");
  }
};

const pasteImage = (event: any) => {
  // console.log("paste image");
  if (
    event.clipboardData &&
    event.clipboardData?.items &&
    event.clipboardData?.items?.length
  ) {
    let items = event.clipboardData?.items;
    let file = null;
    for (let i = 0; i < items.length; i++) {
      if (items[i].type.indexOf("image") !== -1) {
        file = items[i].getAsFile();
        break;
      }
    }

    const blob = URL.createObjectURL(file);
    const reader = new FileReader();
    reader.onload = (e) => {
      formEdit.image = {
        src: blob,
        type: getMimeType(e.target.result, file.type),
      };
    };
    reader.readAsArrayBuffer(file);
  }
};

const handleClose = () => {
  //   if (formEdit.image.src) {
  //     URL.revokeObjectURL(formEdit.image.src);
  //   }
  // 否则预览图不能正常加载
  Object.assign(formEdit, formEditOriginal());
  document.body.removeEventListener("paste", pasteImage);
  state.dialogFormVisible = false;
};

const show = (
  layout: number,
  businessKey: string,
  sender: string,
  fileId: string
) => {
  Object.assign(formEdit, formEditOriginal());
  //   Object.assign(formEdit, row);
  if (fileId) {
    formEdit.image.src = apiUpload.downloadUrl(fileId);
  }
  //   formEdit.image.src =
  //     "https://images.pexels.com/photos/1254140/pexels-photo-1254140.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940";
  loading.value = false;
  state.layout = layout;
  if (layout == 2) {
    state.aspectRatio = 10 / 4.8;
    state.aspectRatio100Height = 72;
    state.aspectRatio50Height = 48;
  } else if (layout == 3) {
    // 图书封面 144/220
    state.aspectRatio = 6 / 10;
    state.aspectRatio100Height = 72;
    state.aspectRatio50Height = 48;
  }
  state.businessKey = businessKey;
  state.sender = sender;
  state.dialogFormVisible = true;

  document.body.addEventListener("paste", pasteImage);
};

defineExpose({
  show,
});
</script>

<style lang="scss" scoped>
.cropper {
  height: 400px;
  width: 550px;
  background: #ddd;
}
.avatar {
  // border-radius: 50%;
  overflow: hidden;
  background: #ddd;
}

.upload-button {
  border: none;
  outline: solid transparent;
  cursor: pointer;
  transition: background 0.5s;
  input {
    display: none;
  }
}
</style>
